package com.study.mike.JWT;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTHeader;
import cn.hutool.jwt.JWTUtil;
import com.study.mike.common.config.JwtConfig;
import com.study.mike.common.utils.AesUtil;
import com.study.mike.common.utils.EncryptUtils;
import com.study.mike.model.entity.User;
import io.jsonwebtoken.*;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author kh
 */
@SpringBootTest
public class Jwt {
    // 定义一个签名的key
    private String signature = "kanghui";

    /**
     * 生成jwtToken
     */
    @Test
    void generateJWT() {
        // 创建jwt对象
        JwtBuilder jwtBuilder = Jwts.builder();
        // 明确jwt的三分部分：heard + payload + signature
        String jwtToken = jwtBuilder
                //1.heard
                // 类型
                .setHeaderParam("typ", "jwt")
                // 加密算法
                .setHeaderParam("alg", "HS256")
                //2.负载 payload
                .claim("username", "KANGHUI")
                .claim("gender", "man")
                // 主题
                .setSubject("learn")
                // 设置有效时间：获取当前系统时间再加上2小时
                .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 24))
                // 设置id 通过UUID生成
                .setId(UUID.randomUUID().toString())
                //3.signature
                .signWith(SignatureAlgorithm.HS256, signature)
                // 拼接 heard、payload、signature
                .compact();
        System.out.println(jwtToken);
    }

    //
    @Test
    void verificationJWT() {
        // 创建解密对象
        JwtParser jwtParser = Jwts.parser();
        // 获取到的token
        String jtwToken = "eyJ0eXAiOiJqd3QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6IktBTkdIVUkiLCJnZW5kZXIiOiJtYW4iLCJzdWIiOiJsZWFybiIsImV4cCI6MTY1Nzc3ODkwOSwianRpIjoiM2Y1YTU3MmQtMGJjZi00NzkzLWI0M2MtMTQ2ZDMzYzIwYjdhIn0.HOYljak-mXl8OKhrbbjkWJHpID0Lr93dm97Mwgc-K1o";
        // 通过签名
        Jws<Claims> claimsJws = jwtParser.setSigningKey(signature).parseClaimsJws(jtwToken);
        Claims claims = claimsJws.getBody();
        System.out.println(claims.get("username"));
        System.out.println(claims.get("gender"));
        System.out.println(claims.getId());
        System.out.println(claims.getSubject());
        // 有效期
        System.out.println(claims.getExpiration());
    }

    // 测试调用jwtConfig对象
    @Test
    void getJwtConfig() {
        JwtConfig jwtConfig = new JwtConfig();
        // 获取到用户信息
        User user = new User();
        user.setName("james");
        user.setAge(23);
        // 获取token
        String token = jwtConfig.generateJWT(user);
        System.out.println(token);
        // 验证token
        if (StrUtil.isNotBlank(token)) {
            jwtConfig.verificationJWT(token);
        }
    }

    @Test
    void helloJunit(HttpServletResponse response) {
        // 注入cookie相关内容，写入到浏览器中
        Cookie cookie = new Cookie("officemate", "eyJ0eXAiOiJqd3QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6IktBTkdIVUkiLCJnZW5kZXIiOiJtYW4iLCJzdWIiOiJsZWFybiIsImV4cCI6MTY1NDUwMDQxOCwianRpIjoiOTEyOGU5NmItNTk5Yi00YzllLTg5OTctODI3ZjA5YWY1NTM5In0.LOcwlLP42S2MUgRMv0aaBDvZ79Lj5FXl--eSYfwoVLU");
        response.addCookie(cookie);
    }

    /**
     * hutool提供的jwt工具类
     */
    @Test
    void jwtUtilTest() {
        // 创建对象
        JWTUtil jwtUtil = new JWTUtil();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("username", "康辉");
        map.put("password", "test");
        System.out.println(jwtUtil.createToken(map, "test".getBytes()));

        // 解析
        final JWT jwt = JWTUtil.parseToken("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJwYXNzd29yZCI6InRlc3QiLCJ1c2VybmFtZSI6IuW6t-i-iSJ9._olygBKrrHF4OXeBYVvdEu_hzKIAR0z9NV-HqSXa2vE");
        jwt.getHeader(JWTHeader.TYPE);
        System.out.println(jwt.getPayload("username"));
    }

    @Test
    void AesUtilTest() {
        // 待加密文本
        String context = "卢伟";
        // 随机生成一个密匙
        byte[] key = SecureUtil.generateKey(SymmetricAlgorithm.AES.getValue()).getEncoded();

        // 构建
        SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key);

        // 加密
        byte[] encrypt = aes.encrypt(context);

        // 解密
        byte[] decrypt = aes.decrypt(encrypt);

        // 加密16进制表示
        String encryptHex = aes.encryptHex(context);

        // 解密字符串
        String decryptStr = aes.decryptStr(encryptHex, CharsetUtil.CHARSET_UTF_8);
        System.out.println(Base64.encode(encrypt) + "通过base64转码");
        System.out.println(encryptHex);
        System.out.println(decryptStr);
    }

    @Test
    void base64UtilTest() {
        String str = "此时无声胜有声";
        // 转化
        String encode = Base64.encode(str);
        System.out.println("转化后数据:" + encode);

        // 还原的数据
        String decodeStr = Base64.decodeStr(encode);
        System.out.println("还原后数据:" + decodeStr);

//        String decodeStrOne = java.util.Base64.getEncoder().encodeToString(new byte[0]);

        System.out.println(java.util.Base64.getDecoder().decode(encode));

    }

    @Test
    void test1() {
        System.out.println(AesUtil.encrypt("james"));
        System.out.println(AesUtil.decrypt("JDbU38naRqFUi8FqQ3h3yQ=="));
    }

    @Test
    void testBCrypt() {
        String nPwd = BCrypt.hashpw("KANGHUI1016", BCrypt.gensalt());
        System.out.println(nPwd);
        System.out.println(BCrypt.checkpw("KANGHUI1016", nPwd));
        System.out.println(BCrypt.gensalt());
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        String encodedPassword = encoder.encode("KANGHUI1016");
        System.out.println(encodedPassword);
    }

    @Test
    void testEncryptUtil() {
//        System.out.println(EncryptUtils.aesEncrypt("康辉"));
        System.out.println(EncryptUtils.aesEncrypt("12186571651"));
//        System.out.println(EncryptUtils.aesEncrypt("kanghui@officemate.cn"));
//        System.out.println(EncryptUtils.aesEncrypt(""));
//        System.out.println(EncryptUtils.aesDecrypt("5e0a8b6837a0354306ab5075c132af00"));
//        System.out.println(EncryptUtils.aesDecrypt("dsa1BRPOtiQMPBRqujuDnw===="));
        System.out.println(EncryptUtils.aesEncrypt("zengfeiyue"));
        System.out.println(EncryptUtils.aesEncrypt("qxt_EKF5fJF"));
        System.out.println(EncryptUtils.aesDecrypt("rQP2MpdhJHUAwBxd1Z3B6A=="));
    }
}
